#include <QtGui>

#include "mapScene.h"
#include "appConfig.h"

MapScene::MapScene(QMenu *itemMenu, QObject *parent) : QGraphicsScene(parent)
{
	showMouseTarget = false;
    myItemMenu = itemMenu;
    myMode = MoveItem;
    myItemType = MapItem::Step;
    line = 0;
    myItemColor = Qt::white;
    myTextColor = Qt::black;
    myLineColor = Qt::black;

	startsCounter = 0;
	currentPathId = 0;

	QPen targetPen = QPen("red");
	targetPen.setWidth(2);
	mouseTarget = addRect(QRectF(1,1,39,39), targetPen, QBrush());
	//mouseTarget = addPixmap(QPixmap(":/Resources/target.png"));
	mouseTarget->setVisible(false);
}


void MapScene::setItemColor(const QColor &color)
{
    myItemColor = color;
    if (isItemChange(MapItem::Type)) {
        MapItem *item =
            qgraphicsitem_cast<MapItem *>(selectedItems().first());
        //item->setBrush(myItemColor);
    }
}

void MapScene::clearAll()
{
	startsCounter = 0;
	for(int i = items().count()-1; i >= 0; i--)
	{
		if(items().at(i)->zValue() != 2)
		{
			removeItem(items().at(i));
		}
	}
}

void MapScene::setMode(Mode mode)
{
    myMode = mode;
}

void MapScene::setItemType(MapItem::DiagramType type)
{
    myItemType = type;
}

void MapScene::itemAtPosExisit(QPointF &pos, MapItem* itemNew)
{
	QList<QGraphicsItem*> itemList = this->items(pos);


	foreach(QGraphicsItem *item, itemList)
	{
		if(item->zValue() != 2)
		{
			if(item->pos().x() == pos.x() && item->pos().y() == pos.y())
			{
				if(itemNew->zValue() == item->zValue())
				{
					removeItem(item);
				}
			}
		}
	}
}

void MapScene::addSpecificTile(QPoint position, MapItem::DiagramType  diagramType)
{
	int cellSize = AppConfig::cellWidth;
	MapItem* item = new MapItem(diagramType, myItemMenu);
	//item->setBrush(myItemColor);
	addItem(item);
	item->setPos(position.x() * cellSize, position.y() * cellSize);
	emit itemInserted(item);
}

void MapScene::showPathWithId(int id)
{
	foreach(QGraphicsItem *item, items())
	{
		if(item->zValue() == 10+id)
		{
			item->show();
		}
	}
}

void MapScene::setPathGroupId(int id)
{
	currentPathId = id;
}

void MapScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    if (mouseEvent->button() != Qt::LeftButton)
	{
        return;
	}
	if(myMode == InsertItem)
	{
		int cellSize = AppConfig::cellWidth;
		MapItem *item;
		QPointF point = mouseEvent->scenePos();
		point.setX((qFloor(point.x()/cellSize)*cellSize));
		point.setY((qFloor(point.y()/cellSize)*cellSize));
		item = new MapItem(myItemType, myItemMenu);
		//item->setBrush(myItemColor);
		if(myItemType == MapItem::DiagramType::Path)
		{
			item->setZValue(10+currentPathId);
		}
		itemAtPosExisit(point, item);
		addItem(item);
		item->setPos(point.x(), point.y());
		emit itemInserted(item);

		if(myItemType == MapItem::DiagramType::Start)
		{
			item->entryId = startsCounter;
			emit startInserted(startsCounter++);
		}
	}
	QGraphicsScene::mousePressEvent(mouseEvent);
}

void MapScene::addPathCell(QPoint position, int id)
{
	int cellSize = AppConfig::cellWidth;
	MapItem* item = new MapItem(MapItem::DiagramType::Path, myItemMenu);
	//item->setBrush(myItemColor);
	addItem(item);
	item->setPos(position.x() * cellSize, position.y() * cellSize);
	item->setZValue(10+id);
	item->hide();
	emit itemInserted(item);
}

void MapScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
	if (myMode == MoveItem) 
	{
        QGraphicsScene::mouseMoveEvent(mouseEvent);
    }
	if(QApplication::mouseButtons() == Qt::MouseButtons::enum_type::LeftButton && myMode == InsertItem)
	{
		if(!(myItemType == MapItem::DiagramType::Start))
		{
			int cellSize = AppConfig::cellWidth;
			MapItem *item;
			QPointF point = mouseEvent->scenePos();
			point.setX((qFloor(point.x()/cellSize)*cellSize));
			point.setY((qFloor(point.y()/cellSize)*cellSize));
			item = new MapItem(myItemType, myItemMenu);
			//item->setBrush(myItemColor);
		


			if(myItemType == MapItem::DiagramType::Path)
			{
				item->setZValue(10+currentPathId);
			}
			itemAtPosExisit(point, item);
			addItem(item);
			item->setPos(point.x(), point.y());
			emit itemInserted(item);

			if(myItemType == MapItem::DiagramType::Start)
			{
				emit startInserted(startsCounter++);
			}
		}
	}
	setMouseTargetPosition(mouseEvent->scenePos());
}

bool MapScene::event ( QEvent * event )
{
	if(event->type() == QEvent::Type::Enter)
	{
		showMouseTarget = true;
	}
	else if(event->type() == QEvent::Type::Leave)
	{
		showMouseTarget = false;
		mouseTarget->setVisible(false);
	}
	return QGraphicsScene::event(event);
}

void MapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    if (line != 0 && myMode == InsertLine) {
        QList<QGraphicsItem *> startItems = items(line->line().p1());
        if (startItems.count() && startItems.first() == line)
            startItems.removeFirst();
        QList<QGraphicsItem *> endItems = items(line->line().p2());
        if (endItems.count() && endItems.first() == line)
            endItems.removeFirst();

        removeItem(line);
        delete line;

        if (startItems.count() > 0 && endItems.count() > 0 &&
            startItems.first()->type() == MapItem::Type &&
            endItems.first()->type() == MapItem::Type &&
            startItems.first() != endItems.first()) {
            MapItem *startItem =
                qgraphicsitem_cast<MapItem *>(startItems.first());
            MapItem *endItem =
                qgraphicsitem_cast<MapItem *>(endItems.first());
        }
    }
    line = 0;
    QGraphicsScene::mouseReleaseEvent(mouseEvent);
}

bool MapScene::isItemChange(int type)
{
    foreach (QGraphicsItem *item, selectedItems()) {
        if (item->type() == type)
            return true;
    }
    return false;
}

void MapScene::setMouseTargetPosition(QPointF scenePoint)
{
	if(showMouseTarget)
	{
		int cellSize = AppConfig::cellWidth;
		QPointF point(0,0);
		point.setX(qFloor(scenePoint.x()/cellSize)*cellSize);
		point.setY(qFloor(scenePoint.y()/cellSize)*cellSize);
		mouseTarget->setPos(point.x(), point.y());
		mouseTarget->setZValue(2);
		mouseTarget->setVisible(true);
	}
}

void MapScene::hideAllPaths()
{
	foreach(QGraphicsItem *item, items())
	{
		if(item->zValue() >= 8)
		{
			item->hide();
		}
	}
}